/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * Factory hook that allows for custom modification of new bean instances &mdash;
 * for example, checking for marker interfaces or wrapping beans with proxies.
 * <br/>允许自定义修改新bean实例的工厂钩子—例如，检查标记接口或用代理包装bean。
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 * <br/>通常，通过标记接口或类似的方式填充bean的后置处理器将实现{@link #postProcessBeforeInitialization}，
 * 而使用代理包装bean的后处理器通常将实现{@link #postProcessAfterInitialization}。
 *
 * <h3>Registration</h3>
 * <p>An {@code ApplicationContext} can autodetect {@code BeanPostProcessor} beans
 * in its bean definitions and apply those post-processors to any beans subsequently
 * created. A plain {@code BeanFactory} allows for programmatic registration of
 * post-processors, applying them to all beans created through the bean factory.
 * <br/>ApplicationContext可以在其bean定义中自动检测实现BeanPostProcessor的bean，并将这些后处理程序应用于
 * 随后创建的任何bean。 普通的BeanFactory允许以编程方式注册后处理器，将它们应用到通过bean工厂创建的所有bean。
 *
 * <h3>Ordering</h3>
 * <p>{@code BeanPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanPostProcessor} beans that are registered programmatically with a
 * {@code BeanFactory} will be applied in the order of registration; any ordering
 * semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanPostProcessor} beans.
 * <br/>在ApplicationContext中自动检测到实现BeanPostProcessor的bean将根据{@link org.springframework.core.PriorityOrdered}
 * 和{@link org.springframework.core.Ordered}语义进行排序。 相反，以编程方式在BeanFactory中注册的BeanPostProcessor bean
 * 将按注册的顺序应用; 对于以编程方式注册的后处理器，通过实现{@code PriorityOrdered}或{@code Ordered}接口表示的任何排序语义都将被忽略。
 * 此外，BeanPostProcessor bean没有考虑{@link org.springframework.core.Ordered}注解。
 *
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @see InstantiationAwareBeanPostProcessor
 * @see DestructionAwareBeanPostProcessor
 * @see ConfigurableBeanFactory#addBeanPostProcessor
 * @see BeanFactoryPostProcessor
 * @since 10.10.2003
 */
public interface BeanPostProcessor {

    /**
     * Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <br/>在任何bean初始化回调之前(如InitializingBean的afterPropertiesSet或自定义初始化方法)，
     * 将此BeanPostProcessor应用到给定的新bean实例。 bean将已经被属性值填充。 返回的bean实例可能是原始bean的包装器。
     * <p>The default implementation returns the given {@code bean} as-is.
     * <br/>默认实现按原样返回给定的bean。
     *
     * @param bean     the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <br/>在任何bean初始化回调之后(如InitializingBean的afterPropertiesSet或自定义初始化方法)，
     * 将此BeanPostProcessor应用到给定的新bean实例。 bean将已经被属性值填充。 返回的bean实例可能是原始bean的包装器。
     * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
     * instance and the objects created by the FactoryBean (as of Spring 2.0). The
     * post-processor can decide whether to apply to either the FactoryBean or created
     * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
     * <br/>对于FactoryBean，将为FactoryBean实例和FactoryBean创建的对象(从Spring 2.0开始)调用此回调。
     * 后处理器可以通过相应的bean instanceof FactoryBean检查来决定是应用于FactoryBean还是应用于已创建的对象，或者两者都应用。
     * <p>This callback will also be invoked after a short-circuiting triggered by a
     * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
     * in contrast to all other {@code BeanPostProcessor} callbacks.
     * <br/>这个回调也会在触发短路后通过{@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}
     * 方法被调用，与所有其他BeanPostProcessor回调方法相反。
     * <p>The default implementation returns the given {@code bean} as-is.
     *
     * @param bean     the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     * @see org.springframework.beans.factory.FactoryBean
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}
